
import cv2
from PySide2.QtWidgets import QApplication, QLabel
from PySide2.QtGui import QPixmap, QImage
from PySide2.QtCore import QTimer, Signal

Success, Failure, Play, Stop, Pause, Start = range(6)

# TODO 没有声音
class VideoPlayer(QLabel):

    progressChanged = Signal(int)
    stateChanged = Signal(int)

    def __init__(self):
        super(VideoPlayer, self).__init__()
        self.playing = False
        self.video = None

        desktop = QApplication.desktop()
        self.setMaximumSize(desktop.width(), desktop.height())

        self.v_timer = QTimer()
        self.v_timer.timeout.connect(self.playVideo)

    def setVideo(self, video):
        if not video:
            print("空视频")
            return
        self.video = video
        self.cap = cv2.VideoCapture(self.video)
        if not self.cap:
            self.stateChanged.emit(Failure)
            return

        self.fps = self.cap.get(cv2.CAP_PROP_FPS)  # 码率
        self.total_frame = self.cap.get(cv2.CAP_PROP_FRAME_COUNT)  # 帧数
        self.current_frame = self.cap.get(cv2.CAP_PROP_POS_FRAMES)
        # 总秒
        self.total_second = int(self.total_frame/self.fps)

        self.stateChanged.emit(Success)

        self.playVideo()

    def playVideo(self):
        success, frame = self.cap.read()
        if not success:
            return
        # Mat格式图像转Qt中图像的方法
        show = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        showImage = QImage(
            show.data, show.shape[1], show.shape[0], show.shape[1]*3, QImage.Format_RGB888)
        self.setPixmap(QPixmap.fromImage(showImage))
        self.current_frame = self.cap.get(cv2.CAP_PROP_POS_FRAMES)
        self.current_second = int(self.current_frame/self.fps)

        self.progressChanged.emit(self.current_second)

    def position(self, second):
        if not self.video or not self.cap:
            return
        frame = self.fps * second
        self.cap.set(cv2.CAP_PROP_POS_FRAMES, float(frame))
        self.playVideo()

    def play(self):
        if not self.video or self.playing:
            return
        self.playing = True
        self.v_timer.start(int(1000/self.fps))
        self.stateChanged.emit(Play)

    def stop(self):
        if not self.video or not self.playing:
            return
        self.playing = False
        self.v_timer.stop()
        self.stateChanged.emit(Stop)

    def pause(self):
        if not self.video or not self.playing:
            return
        self.playing = False
        self.v_timer.stop()
        self.stateChanged.emit(Pause)

    def start(self):
        if not self.video or self.playing:
            return
        self.playing = True
        self.position(0)
        self.v_timer.start(int(1000/self.fps))
        self.stateChanged.emit(Start)

    def format_time(self, second):
        return "{}:{}:{}".format(int(second/3600), int((second % 3600)/60), int(second % 60))
